package template;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.android.dom.manifest.Application;
import org.jetbrains.android.dom.manifest.Manifest;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;

public class RubbishProduceAction extends AnAction {
    private String[] wordPool;
    private Project mProject;
    //绝对路径
    private String mPath;
    //layout 路径
    private String mLayoutPath;
    //import 的包名
    private String mPackageName;
    //App 包名
    private String mBasePackageName;

    private int mLimitCount;
    private String mCurrentName, nextName;

    @Override
    public void actionPerformed(AnActionEvent e) {
        mProject = e.getProject();
        PsiFile manifestFile = getManifestFile(mProject);
        if (manifestFile == null) {
            Messages.showMessageDialog(mProject, "没找到Manifest，无法继续", "垃圾生产插件", Messages.getInformationIcon());
            return;
        }
        //使用Dom方式解析 Manifest.xml
        for (PsiElement psiElement : manifestFile.getChildren()) {
            System.out.println(psiElement);
        }
        DomManager manager = DomManager.getDomManager(mProject);
        DomFileElement<Manifest> domFileElement = manager.getFileElement((XmlFile) manifestFile, Manifest.class);
        Manifest ma = domFileElement.getRootElement();
        Application application = ma.getApplication();

        VirtualFile mSelectFolder = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
        mLayoutPath = mProject.getBasePath() + "\\app\\src\\main\\res\\layout";
        if (mSelectFolder == null) {
            Messages.showMessageDialog(mProject, "Root path not caught", "垃圾生产插件", Messages.getInformationIcon());
            return;
        }
        //绝对路径类似：D:\demo\dem3\app\src\main\java\com\smyk\demo3
        mPath = mSelectFolder.getPath();
        mPackageName = CommonUtils.getImportPackage(mPath);
        mBasePackageName = CommonUtils.getBasePackage(mPackageName);


        String firstClassName = Messages.showInputDialog(mProject, "请输入第一个Activity的名称", "垃圾生产插件", Messages.getInformationIcon());
        if (firstClassName == null || firstClassName.equals("")) {
            System.out.print("请输入类名");
            return;
        }
        String otherClassName = Messages.showInputDialog(mProject, "请输入其他Activity的名称，以英文逗号隔开", "垃圾生产插件", Messages.getInformationIcon());
        if (otherClassName == null || otherClassName.equals("")) {
            System.out.print("请输入其他类名");
            return;
        }
        wordPool = otherClassName.split(",");
        ArrayList<String> data = new ArrayList<>(Arrays.asList(wordPool));
        mLimitCount = wordPool.length + 1;

       /* String inputLimitCount = Messages.showInputDialog(mProject, "请输入个数", "垃圾生产插件", Messages.getInformationIcon());
        if (inputLimitCount == null || inputLimitCount.equals("")) {
            System.out.print("请输入个数");
            return;
        }
        try {
            mLimitCount = Integer.parseInt(inputLimitCount);
        } catch (NumberFormatException numberFormatException) {
            numberFormatException.printStackTrace();
            System.out.print("请输入正确的个数");
            return;
        }*/

        mCurrentName = firstClassName;
        for (int i = 0; i <= data.size(); i++) {
            if (i == data.size()){
                nextName = data.get(i-1);
            }else {
                nextName = data.get(i);
            }
            addManifest(application, mCurrentName);
            createActivity(e, mCurrentName, nextName);
            if (i<data.size()){
                mCurrentName = data.get(i);
            }
        }


      /*  while (count < mLimitCount) {
            Random random = new Random();
            int index = random.nextInt(data.size());
            if (count == mLimitCount - 1) {
                nextName = mCurrentName;
            } else {
                nextName = data.get(index);
            }
            addManifest(application, mCurrentName);
            createActivity(e, mCurrentName, nextName);
            count++;
            data.remove(index);
            try {
                Thread.sleep(100);
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
        }*/
    }

    private void createActivity(AnActionEvent e, String currentName, String nextName) {
        String xmlName = "activity_" + CommonUtils.camelToUnderline(currentName);
        String activity = readFile("Activity")
                .replace("&package&", mPackageName)
                .replace("&basePackageName&", mBasePackageName)
                .replace("&activityName&", currentName)
                .replace("&xmlName&", xmlName)
                .replace("&methodName&", currentName.toLowerCase(Locale.ROOT))
                .replace("&nextName&", nextName);
        writetoFile(activity, mPath + "/rub", currentName + "Activity.kt");
        //创建xml
        String layout = readFile("Layout")
                .replace("&nextName&", nextName);
        writetoFile(layout, mLayoutPath, xmlName + ".xml");
        CommonUtils.refreshProject(e);
        getLayoutFile(mProject).refresh(false, true);

        mCurrentName = nextName;
    }

    private synchronized void addManifest(Application application, String activityName) {
        String a = "<activity android:name=\"";
        String b = ".rub." + activityName + "Activity";
        String c = "\"/>";
        XmlTag tag = XmlElementFactory.getInstance(mProject).createHTMLTagFromText(a + b + c);
        WriteCommandAction.runWriteCommandAction(mProject, () -> {
            application.getXmlTag().addSubTag(tag, true);
        });
    }

    //
    private String readFile(String filename) {
        InputStream in = null;
        in = this.getClass().getResourceAsStream("code/" + filename);
        String content = "";
        try {
            content = new String(readStream(in));
        } catch (Exception e) {
        }
        return content;
    }

    private void writetoFile(String content, String filepath, String filename) {
        try {
            File floder = new File(filepath);
            // if file doesnt exists, then create it
            if (!floder.exists()) {
                floder.mkdirs();
            }
            File file = new File(filepath + "/" + filename);
            if (!file.exists()) {
                file.createNewFile();
            }
            // OutputStreamWriter fos = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
                System.out.println(new String(buffer));
            }

        } catch (IOException e) {
        } finally {
            outSteam.close();
            inStream.close();
        }
        return outSteam.toByteArray();
    }

    public static PsiFile getManifestFile(Project project) {
        String path = project.getBasePath() + File.separator +
                "app" + File.separator +
                "src" + File.separator +
                "main" + File.separator +
                "AndroidManifest.xml";
        VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
        if (virtualFile == null) return null;
        return PsiManager.getInstance(project).findFile(virtualFile);
    }

    public static VirtualFile getLayoutFile(Project project) {
        String path = project.getBasePath() + File.separator +
                "app" + File.separator +
                "src" + File.separator +
                "main" + File.separator +
                "res" + File.separator +
                "layout";
        return LocalFileSystem.getInstance().findFileByPath(path);
    }

}
